package nodes;

import compiler.Compiler;
import compiler.SymbolTable;
import descriptors.AbstractDescr;
import descriptors.TypeDescr;

public class ModuleNode extends AbstractNode {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	IdentNode ident;
	DeclarationsNode declarations;
	ListNode<StatementNode> body;
	
	public ModuleNode(IdentNode ident,DeclarationsNode declarations,ListNode<StatementNode> body, int line,int column){
		super(line,column);
		this.ident=ident;
		this.declarations=declarations;
		this.body=body;
	}
	
	@Override
	public AbstractDescr compile(
			SymbolTable symbolTable, Compiler compiler) {
		// Add basic types
		symbolTable.set("integer", new TypeDescr(1,compiler.level(),"integer"));
		compiler.write("PUSHS, "+ident.ident());
		int startLabel=compiler.newLabel();
		compiler.write("JMP, "+startLabel);
		declarations.compile(symbolTable, compiler);
		compiler.write("LABEL, "+startLabel);
		compiler.write("PUSHI, 0");
		compiler.write("SETFP, 0");
		compiler.write("PUSHI, "+compiler.address()); // set stack pointer at the top of the stack
		compiler.write("SETSP");
		body.compile(symbolTable, compiler);
		compiler.write("STOP");
		return null;
	}

	@Override
	public void print() {
		trace("ModuleNode");
		ident.print();
		declarations.print();
		body.print();
		unindent();
	}

}
